<template>
  <div class="signed-view">
    <transition-group @before-enter="beforeEnter" @enter="enter" :css="false" tag="div">
      <div v-for="(item,index) in list" :data-index="index" :key="index" v-if="item.show">
        <div class="person">
          <img src="../common/img/a.png" class="person-img">
          <div class="person-talk">{{item.msg }}</div>
        </div>
      </div>
    </transition-group>
    <transition :enter-active-class="animateShowIn" :duration="{ enter: 2000, leave: 800 }">
      <person-dialog class="animated" v-if="showDialog"></person-dialog>
    </transition>
    <div id="signed"></div>
  </div>
</template>

<script>
import Velocity from 'velocity-animate'
import * as THREE from 'three'
import * as TWEEN from 'tween'
import { CSS3DObject, CSS3DRenderer } from '@/common/js/css3drenderer'
import PersonDialog from '@/components/PersonDialog'
/* const colorArr = [
  'Olive',
  'OliveDrab',
  'Orange',
  'OrangeRed',
  'Orchid',
  'PaleGoldenRod',
  'PaleGreen',
  'PaleTurquoise',
  'PaleVioletRed',
  'PapayaWhip',
  'PeachPuff',
  'Peru',
  'Pink',
  'Plum',
  'PowderBlue',
  'Purple',
  'Red',
  'RosyBrown',
  'RoyalBlue',
  'SaddleBrown',
  'Salmon',
  'SandyBrown',
  'SeaGreen',
  'SeaShell',
  'Sienna',
  'Silver',
  'SkyBlue'
] */
const animateIn = [
  'bounceIn',
  'bounceInDown',
  'bounceInLeft',
  'bounceInRight',
  'bounceInUp',
  'fadeIn',
  'fadeInDown',
  'fadeInDownBig',
  'fadeInLeft',
  'fadeInLeftBig',
  'fadeInRight',
  'fadeInRightBig',
  'fadeInUp',
  'fadeInUpBig',
  'rotateIn',
  'rotateInDownLeft',
  'rotateInDownRight',
  'rotateInUpLeft',
  'rotateInUpRight',
  'slideInDown',
  'slideInLeft',
  'slideInRight'
]
const animateOut = [
  'bounceOut',
  'bounceOutDown',
  'bounceOutLeft',
  'bounceOutRight',
  'bounceOutUp',
  'fadeOut',
  'fadeOutDown',
  'fadeOutDownBig',
  'fadeOutLeft',
  'fadeOutLeftBig',
  'fadeOutRight',
  'fadeOutRightBig',
  'fadeOutUp',
  'fadeOutUpBig',
  'rotateOut',
  'rotateOutDownLeft',
  'rotateOutDownRight',
  'rotateOutUpLeft',
  'rotateOutUpRight',
  'slideOutDown',
  'slideOutLeft',
  'slideOutRight'
]
export default {
  name: 'SignedView',
  data () {
    return {
      list: [],
      table: [],
      camera: null,
      scene: null,
      renderer: null,
      targets: { table: [], sphere: [], helix: [], grid: [] },
      objects: [],
      animateShowIn: '',
      animateShowOut: '',
      showDialog: false,
      curPersonNum: 0
    }
  },
  methods: {
    beforeEnter (el) {
      let windowHeight = window.outerHeight - 100
      let bottom = Math.floor(Math.random() * windowHeight + 20)
      if (bottom + 200 > windowHeight) {
        bottom = window.outerHeight - 200
      }
      el.style.position = 'fixed'
      el.style.right = '-500px'
      el.style.bottom = bottom + 'px'
      el.style.color =
        'yellow' /* colorArr[Math.floor(Math.random() * colorArr.length)] */
      el.style.minWidth = '500px'
      el.style.zIndex = 9999
    },
    enter (el, done) {
      let that = this
      let width = window.innerWidth
      Velocity(
        el,
        { right: width + 500 + 'px' },
        {
          duration: 10000,
          complete: function () {
            done()
            that.list[el.dataset.index].show = false
          }
        }
      )
    },
    getImgs () {
      let row = 1
      let col = 1
      for (var i = 0; i < 198; i++) {
        var file = {}
        file.img =
          'http://wx.qlogo.cn/mmopen/vi_32/iavhNQNYg0tY5DFibJNnOmsWoT1MYSZYPia52DvjWeUicdvJ5r79rSjGGpIVVicqGkWa5ib6FaXVe6YxxnIKsHXCxXKQ/132'
        file.p_x = col++
        file.p_y = row
        this.table[i] = file
        if (col > 18) {
          col = 1
          row++
        }
      }
    },
    init () {
      this.camera = new THREE.PerspectiveCamera(
        50,
        window.innerWidth / window.innerHeight,
        1,
        10000
      )
      this.camera.position.z = 3000
      this.scene = new THREE.Scene()
      this.createTable()
      this.createSphere()
      this.createHelix()
      this.createGrid()
      this.renderer = new CSS3DRenderer()
      this.renderer.setSize(window.innerWidth, window.innerHeight)
      this.renderer.domElement.style.position = 'absolute'
      document.getElementById('signed').appendChild(this.renderer.domElement)
      var ini = 0
      setInterval(() => {
        ini = ini >= 4 ? 0 : ini
        ++ini
        switch (ini) {
          case 1:
            this.transform(this.targets.sphere, 2000)
            break
          case 2:
            this.transform(this.targets.helix, 2000)
            break
          case 3:
            this.transform(this.targets.grid, 2000)
            break
          case 4:
            this.transform(this.targets.table, 2000)
            break
        }
      }, 4000)

      this.transform(this.targets.grid, 2000)
      window.addEventListener('resize', this.onWindowResize, false)
    },
    createTable () {
      for (let i = 0; i < this.table.length; i++) {
        let element = document.createElement('div')
        element.className = 'element'
        element.style.backgroundColor =
          'rgba(0,127,127,' + (Math.random() * 0.5 + 0.25) + ')'

        let img = document.createElement('img')
        img.src = this.table[i].img
        img.style.width = '100%'
        img.style.height = '100%'
        element.appendChild(img)

        let object = new CSS3DObject(element)
        object.position.x = Math.random() * 4000 - 2000
        object.position.y = Math.random() * 4000 - 2000
        object.position.z = Math.random() * 4000 - 2000

        this.scene.add(object)

        this.objects.push(object)

        let object1 = new THREE.Object3D()
        object1.position.x = this.table[i].p_x * 140 - 1330
        object1.position.y = -(this.table[i].p_y * 180) + 990
        this.targets.table.push(object1)
      }
    },
    createSphere () {
      let vector = new THREE.Vector3()
      for (let i = 0, l = this.objects.length; i < l; i++) {
        let phi = null
        let theta = null
        phi = Math.acos(-1 + 2 * i / l)
        theta = Math.sqrt(l * Math.PI) * phi
        let object = new THREE.Object3D()

        object.position.x = 800 * Math.cos(theta) * Math.sin(phi)
        object.position.y = 800 * Math.sin(theta) * Math.sin(phi)
        object.position.z = 800 * Math.cos(phi)

        vector.copy(object.position).multiplyScalar(2)
        object.lookAt(vector)
        this.targets.sphere.push(object)
      }
    },
    createHelix () {
      let vector = new THREE.Vector3()
      for (let i = 0, l = this.objects.length; i < l; i++) {
        let phi = i * 0.175 + Math.PI

        let object = new THREE.Object3D()

        object.position.x = 900 * Math.sin(phi)
        object.position.y = -(i * 8) + 850
        object.position.z = 900 * Math.cos(phi)

        vector.x = object.position.x * 2
        vector.y = object.position.y
        vector.z = object.position.z * 2

        object.lookAt(vector)
        this.targets.helix.push(object)
      }
    },
    createGrid () {
      for (let i = 0; i < this.objects.length; i++) {
        let object = new THREE.Object3D()
        object.position.x = (i % 5) * 400 - 800
        object.position.y = -(Math.floor(i / 5) % 5) * 400 + 800
        object.position.z = Math.floor(i / 25) * 500 - 1000
        this.targets.grid.push(object)
      }
    },
    transform (targets, duration) {
      TWEEN.removeAll()
      for (let i = 0; i < this.objects.length; i++) {
        let object = this.objects[i]
        let target = targets[i]
        new TWEEN.Tween(object.position)
          .to(
          {
            x: target.position.x,
            y: target.position.y,
            z: target.position.z
          },
            Math.random() * duration + duration
          )
          .easing(TWEEN.Easing.Exponential.InOut)
          .start()
        new TWEEN.Tween(object.rotation)
          .to(
          {
            x: target.rotation.x,
            y: target.rotation.y,
            z: target.rotation.z
          },
            Math.random() * duration + duration
          )
          .easing(TWEEN.Easing.Exponential.InOut)
          .start()
      }
      new TWEEN.Tween(this)
        .to({}, duration * 2)
        .onUpdate(this.render)
        .start()
    },
    onWindowResize () {
      this.camera.aspect = window.innerWidth / window.innerHeight
      this.camera.updateProjectionMatrix()
      this.renderer.setSize(window.innerWidth, window.innerHeight)
    },
    animate () {
      requestAnimationFrame(this.animate)
      TWEEN.update()
    },
    render () {
      this.scene.rotation.y += 0.018
      this.renderer.render(this.scene, this.camera)
    }
  },
  mounted () {
    setTimeout(() => {
      this.getImgs()
      this.init()
      this.animate()
      setInterval(() => {
        let randIn = parseInt(Math.random() * animateIn.length, 10)
        let randOut = parseInt(Math.random() * animateOut.length, 10)
        this.animateShowIn = animateIn[randIn]
        this.animateShowOut = animateIn[randOut]
        if (this.curPersonNum >= this.table.length) {
          this.curPersonNum = 0
        }
        setTimeout(() => {
          this.showDialog = true
        }, 1000)
        setTimeout(() => {
          let img = document
            .getElementsByClassName('element')[this.curPersonNum].getElementsByTagName('img')[0]
          img.setAttribute(
            'src',
            'http://wx.qlogo.cn/mmopen/vi_32/iavhNQNYg0tY5DFibJNnOmsWoT1MYSZYPia52DvjWeUicdvJ5r79rSjGGpIVVicqGkWa5ib6FaXVe6YxxnIKsHXCxXKQ/132'
          )
          this.curPersonNum++
          this.showDialog = false
        }, 3000)
      }, 4500)
      setInterval(() => {
        this.list.push({
          msg: '新年快乐',
          show: true
        })
      }, 500)
    }, 300)
  },
  components: {
    PersonDialog
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="less">
.signed-view {
  .person {
    height: 91px;
    .person-img {
      border-radius: 50%;
      border: 1px solid #fff;
      width: 60px;
      height: 60px;
      display: inline-block;
      vertical-align: middle;
    }
    .person-talk {
      display: inline-block;
      word-break: break-all;
      word-wrap: break-word;
      max-width: 400px;
      line-height: 36px;
      font-size: 36px;
      margin-left: -12px;
      padding: 10px;
      vertical-align: middle;
      border-right: 1px solid #fff;
      border-top-right-radius: 50px;
      border-bottom-right-radius: 50px;
      border-top: 1px solid #fff;
      border-bottom: 1px solid #fff;
    }
  }
  #signed {
    .element {
      width: 120px;
      height: 120px;
      box-shadow: 0px 0px 12px rgba(0, 255, 255, 0.5);
      border: 1px solid rgba(127, 255, 255, 0.25);
      cursor: default;
      img {
        position: absolute;
        border: none;
        border-radius: 15px;
      }
    }
  }
}
</style>
